package com.gitee.proxy.handler;

import com.gitee.proxy.handler.proxy.ProxyHttpRequest;
import com.gitee.proxy.server.ServerConfig;
import com.gitee.proxy.util.LogUtil;
import com.gitee.proxy.util.ProxyRequestUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.util.ReferenceCountUtil;

public class ServerHandler extends ChannelInboundHandlerAdapter {

    private ServerConfig serverConfig;

    private ProxyHttpRequest proxyHttpRequest;

    public ServerHandler(ServerConfig serverConfig) {
        this.serverConfig = serverConfig;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof HttpRequest) {
            HttpRequest request = (HttpRequest) msg;
            ProxyHttpRequest proxyRequest = ProxyRequestUtil.parserHttpProxyRequest(request, serverConfig);
            if (this.proxyHttpRequest == null) {
                this.proxyHttpRequest = proxyRequest;
            } else {
                this.proxyHttpRequest.setHost(proxyRequest.getHost());
                this.proxyHttpRequest.setPort(proxyRequest.getPort());
                this.proxyHttpRequest.setHttps(false);
            }
            if (proxyRequest == null) {
                ReferenceCountUtil.release(msg);
                return;
            }
            if (HttpMethod.CONNECT.equals(request.method())) {// https 会先发送CONNECT
                this.proxyHttpRequest.getHandler()
                        .handleConnectData(ctx, msg);
                proxyRequest.setHttps(true);
                return;
            }
            this.proxyHttpRequest.getHandler()
                    .handleProxyData(ctx, this.proxyHttpRequest, msg);
        } else {
            this.proxyHttpRequest.getHandler()
                    .handleProxyData(ctx, this.proxyHttpRequest, msg);
        }
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        this.proxyHttpRequest.close();
        ctx.channel().close();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        LogUtil.error(ServerHandler.class, "请求发生异常", cause);
        this.proxyHttpRequest.close();
        ctx.channel().close();
    }
}
